package group_01.MultiSnakeServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.LinkedList;
import java.util.Observable;

/**
 * 
 * @author Martin Nume
 * PlayerHandler is the connection between the client and the game on the server side.
 * Takes care of all the sending and receiving of data. Every player has its own PlayerHandler.
 *
 */
public class PlayerHandler extends Observable implements Runnable{
	private Thread thread;
	private String playerID;
	private String playerName;
	
	private Socket clientSocket;
	private LinkedList<String> outBuffer;
	private BufferedReader in;
	private PrintWriter out;

	
	public PlayerHandler(String playerName, Socket socket) {
		this.playerName = playerName;
		this.clientSocket = socket;
		outBuffer = new LinkedList<String>();
		playerID="";
		in = null;
		out = null;
		thread = new Thread(this);
		
	}
	public void start() {
		thread.start();
	}
	
	public void setPlayerID(String id) {
		playerID=id;
		
	}
	public String getPlayerID() {
		return playerID;
	}
	public String getPlayerName() {
		return playerName;
	}
	
	public void stopThread() {
		thread.interrupt();
	}

	/**
	 * Add data to the outgoing queue
	 * @param str = data to be sent to the client
	 */
	public void pushToBuffer(String str) {
		outBuffer.add(str);
	}
	public boolean isSocketOpen(){
		return clientSocket.isConnected();
	}
	
	@Override
	public void run() {
		try {
				try {
					//instream
					in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
					//outstream
					out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
					String text ="";
					
					
					
					while(!Thread.interrupted()) {
							try {
								Thread.sleep(1);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						
							if( in.ready()){
								if((text = in.readLine()) != null){
									//notifys the Gamehandler that this PlayerHandler has received data from its client.
									setChanged();
									notifyObservers(text);
								}
							}
							//if the GameHandler has added data for the outgoing buffer it will be sent here
							if(outBuffer.size() > 0){
							String textOut = outBuffer.poll();
							
								out.println(textOut);
								out.flush();
							}
					}
				}
				//clean up connections
				finally {
					if(out !=null)
						out.close();
					if(in != null)
						in.close();
					if(clientSocket != null)
						clientSocket.close();	
				}
		} 
		catch (SocketException es) {
		System.out.println("Client didnt reconnect to the assigned port in PlayerHandler");	
		es.printStackTrace();
		}
		catch (IOException e) {
			
			e.printStackTrace();
		}
	}
	
}
